package com.liebaut.controller.article;

import com.liebaut.controller.CrudController;
import com.liebaut.dao.article.ArticleRepository;
import com.liebaut.dao.article.ModelRepository;
import com.liebaut.dao.article.SizeRepository;
import com.liebaut.exception.RestException;
import com.liebaut.model.articles.*;
import org.codehaus.jackson.JsonProcessingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.repository.CrudRepository;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

import static com.liebaut.util.MapUtil.map;

@Controller
@RequestMapping("/article")
public class ArticleController extends CrudController<Article, Long> {
    private static final Logger log = LoggerFactory.getLogger(ArticleController.class);

    @Autowired
    private SizeRepository sizeRepository;
    
    @Autowired
    private ModelRepository modelRepository;

    @Autowired
    public ArticleController(ArticleRepository articleRepository) {
        super(articleRepository);
    }

    public ArticleController() {
    }



    @Override
    public Object save(@RequestBody String body) throws IOException {
        long start = System.currentTimeMillis();
        Article entity;
        try {
            entity = saveRequestToEntity(body);

        } catch (JsonProcessingException e) {
            log.debug("invalid request", e);
            throw new HttpMessageNotReadableException("Invalid request", e);
        }
        if(entity.getSizes() != null){
            for(Size size : entity.getSizes()){
                sizeRepository.save(size);
                if(entity.getEanCodes() != null){
                    for(EanCode ean : entity.getEanCodes()){
                        if(size.equals(ean.getSize()))
                            ean.setSize(size);
                    }    
                }
                if(entity.getPrices() != null){
                    for(Price price : entity.getPrices()){
                        if(size.equals(price.getSize()))
                            price.setSize(size);
                    }    
                }
                if(entity.getPurchaseDetails() != null){
                    for(PurchaseDetails purchase : entity.getPurchaseDetails()){
                        if(size.equals(purchase.getSize()))
                            purchase.setSize(size);
                    }    
                }
                if(entity.getStocks() != null){
                    for(Stock stock : entity.getStocks()){
                        if(size.equals(stock.getSize()))
                            stock.setSize(size);
                    }    
                }  
            }    
        }
        
        for(Model model : entity.getModels()){
            modelRepository.save(model);
            if(entity.getEanCodes() != null){
                for(EanCode ean : entity.getEanCodes()){
                    if(model.equals(ean.getModel()))
                        ean.setModel(model);
                }
            }
            if(entity.getPrices() != null){
                for(Price price : entity.getPrices()){
                    if(model.equals(price.getModel()))
                        price.setModel(model);
                }
            }
            if(entity.getPurchaseDetails() != null){
                for(PurchaseDetails purchase : entity.getPurchaseDetails()){
                    if(model.equals(purchase.getModel()))
                        purchase.setModel(model);
                }
            }
            if(entity.getStocks() != null){
                for(Stock stock : entity.getStocks()){
                    if(model.equals(stock.getModel()))
                        stock.setModel(model);
                }
            }
            if(entity.getImages() != null){
                for(Image image : entity.getImages()){
                    if(model.equals(image.getModel()))
                        image.setModel(model);
                }
            }

        }
        repository.save(entity);
        log.info("Article save took "+(System.currentTimeMillis()-start) + " ms.");
        return map("id", entity.getId());
    }

    @RequestMapping(value = "ean/{ean}", method = RequestMethod.GET)
    @ResponseBody
    public Object getArticleByEanCode(@PathVariable int ean){
        Article article = ((ArticleRepository)repository).findByEanCode(ean);
        if (article != null)
            return article;
        else
            throw new RestException(HttpStatus.NOT_FOUND, "Article with eancode not found: " + ean);

    }

    @Override
    public Iterable list(HttpServletRequest request) {
        String number = request.getParameter("articleNumber");
        String supplier = request.getParameter("supplier");
        String page = request.getParameter("page");
        String size = request.getParameter("size");

        int pageNumber = page == null ? 0 : Integer.parseInt(page);
        int sizeNumber = size == null ? 10 : Integer.parseInt(size);

        if(number == null && supplier == null)
            return super.list(request);
        else if(number == null)
            return ((ArticleRepository)repository).findBySupplier(Integer.parseInt(supplier));
        else if(supplier == null)
            return ((ArticleRepository)repository).findByArticleNumberLike(number, new PageRequest(pageNumber, sizeNumber));
        else
            return ((ArticleRepository)repository).findByArticleNumberAndSupplier(number,Integer.parseInt(supplier));
    }
}
